package webapi

import (
	// "bp/cache"
	"bp/conf"
	"bp/db"

	// "bgs/grpc/client"
	internalHttpMiddleware "bp/internal/middleware/http"
	"bp/internal/nsqserver/producer"
	"bp/internal/render"
	"bp/internal/service/com"
	"bp/internal/service/entity"
	"bp/internal/util"
	// couponGrpc "bp/rpc/gen/webapi/coupon"
	cardDiscountWebApiImp "bp/internal/rpcserver/webapi/card_discount_imp"
	couponDistributionWebApiImp "bp/internal/rpcserver/webapi/coupon_distribution_imp"
	couponWebApiImp "bp/internal/rpcserver/webapi/coupon_imp"
	cronWebApiImp "bp/internal/rpcserver/webapi/cron_imp"
	promotionWebApiImp "bp/internal/rpcserver/webapi/promotion_imp"
	"context"
	"fmt"
	"github.com/go-chi/chi"
	httpMiddleware "github.com/go-chi/chi/middleware"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"net/http"
)

// WebApiServer :grpc server proxy of webapi
type WebApiServer struct {
	slog *zap.SugaredLogger
	// cacher *cache.Adapter
}

// NewWebApiServer initialization
func NewWebApiServer(
	s *grpc.Server,
	slog *zap.SugaredLogger,
	pgdao *db.PgDao,
	webConfPtr *conf.WebSection,
	vars *conf.VarsSection,
	pub *producer.NsqProducerProxy,
	entityHub *entity.EntityHub,
	comHub *com.ComHub,
	// proxy *client.GrpcClientProxy,
	// adp *cache.Adapter,
) (ws *WebApiServer) {
	ws = &WebApiServer{
		slog: slog.With("module", "WebApiServer"),
		// cacher:           adp,
		// activityService: activityService,
	}

	go ws.RegisterWeb(slog, pgdao, webConfPtr, vars, pub, entityHub, comHub)

	return
}

// NewContextLogger create a SugaredLogger with contextvalue
func (s *WebApiServer) NewContextLogger(ctx context.Context) *zap.SugaredLogger {
	return util.NewContextLogger(ctx, s.slog)
}

func (s *WebApiServer) RegisterWeb(
	slog *zap.SugaredLogger,
	pgdao *db.PgDao,
	webConfPtr *conf.WebSection,
	vars *conf.VarsSection,
	pub *producer.NsqProducerProxy,
	entityHub *entity.EntityHub,
	comHub *com.ComHub,
) (err error) {

	cardDiscountWebApi := cardDiscountWebApiImp.NewCardDiscountWebApi(slog, pgdao, vars, entityHub)
	couponWebApi := couponWebApiImp.NewCouponWebApi(slog, pgdao, vars, entityHub)
	couponDistributionWebApi := couponDistributionWebApiImp.NewCouponDistributionWebApi(slog, pgdao, vars, entityHub)
	cronWebApi := cronWebApiImp.New(slog, pgdao, vars, pub, entityHub, comHub)
	promotionWebApi := promotionWebApiImp.NewPromotionWebApi(slog, pgdao, vars, entityHub)

	mux := chi.NewMux()
	mux.Use(httpMiddleware.Recoverer)
	mux.Use(httpMiddleware.Logger)
	mux.Use(internalHttpMiddleware.WithCors(slog, vars))
	// mux.Use(internalHttpMiddleware.WithWebToken(slog, vars))

	webApiR := chi.NewRouter()
	webApiR.Use(render.WrapResponse(true))

	webApiR.Route("/", func(r chi.Router) {
		cardDiscountWebApi.RegisterToWeb(r)
		couponWebApi.RegisterToWeb(r)
		couponDistributionWebApi.RegisterToWeb(r)
		cronWebApi.RegisterToWeb(r)
		promotionWebApi.RegisterToWeb(r)
	})
	mux.Mount("/", webApiR)

	pingR := chi.NewRouter()
	pingR.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})
	mux.Mount("/ping", pingR)

	webUrl := fmt.Sprintf("%s:%s", webConfPtr.Host, webConfPtr.Port)
	slog.Info("webapi webserver started")
	http.ListenAndServe(webUrl, mux)
	slog.Info("webapi webserver stoped")
	return
}

// func (s *WebApiServer) getCtxToken(ctx context.Context) (token *util.BilinToken) {
// 	token = ctx.Value(util.BilinTokenKey{}).(*util.BilinToken)
// 	return
// }

// func (s *WebApiServer) getCtxPager(ctx context.Context) (token *util.Pager) {
// 	token = ctx.Value(util.PagerKey{}).(*util.Pager)
// 	return
// }
